using System;
using System.ComponentModel;
using System.Threading;
using WeakEvent;

namespace Common.NotifyEvent
{
	[Serializable]
	public class NotifyPropertyChanged : INotifyPropertyChanged
	{
		private FastSmartWeakEvent<EventHandler> _event = new FastSmartWeakEvent<EventHandler>();

		private SynchronizationContext _synchronizationContext = SynchronizationContext.Current;

		public event EventHandler Event
		{
			add
			{
				_event.Add(value);
			}
			remove
			{
				_event.Remove(value);
			}
		}

		public event PropertyChangedEventHandler PropertyChanged;

		public void RaiseEvent(PropertyChangedEventArgsEx args)
		{
			_event.Raise(this, args);
		}

		public virtual void OnPropertyChanged(string propertyName, object newValue = null, object oldValue = null)
		{
			if (string.IsNullOrEmpty(propertyName))
			{
				throw new ArgumentException("propName");
			}
			PropertyChangedEventArgsEx propertyChangedEventArgsEx = new PropertyChangedEventArgsEx(propertyName);
			propertyChangedEventArgsEx.NewValue = newValue;
			propertyChangedEventArgsEx.OldValue = oldValue;
			PropertyChangedEventArgsEx propertyChangedEventArgsEx2 = propertyChangedEventArgsEx;
			if (SynchronizationContext.Current == _synchronizationContext)
			{
				RaisePropertyChangedEvent(propertyChangedEventArgsEx2);
			}
			else if (_synchronizationContext != null)
			{
				_synchronizationContext.Send(RaisePropertyChangedEvent, propertyChangedEventArgsEx2);
			}
			RaiseEvent(propertyChangedEventArgsEx2);
		}

		private void RaisePropertyChangedEvent(object param)
		{
			if (this.PropertyChanged != null)
			{
				this.PropertyChanged(this, param as PropertyChangedEventArgsEx);
			}
		}
	}
}
